package com.lxk.builder;

import com.lxk.bean.Constants;
import com.lxk.bean.FieldInfo;
import com.lxk.bean.TableInfo;
import com.lxk.utils.DateUtils;
import com.lxk.utils.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

public class BuildPo {
    private static final Logger logger = LoggerFactory.getLogger(BuildPo.class);
    public static void execute(TableInfo tableInfo){
        File folder = new File(Constants.PATH_PO);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        //System.out.println(Constants.PATH_PO);
        File file = new File(folder, tableInfo.getBeanName() + ".java");
//        try{
//            file.createNewFile();
//        }catch (IOException e){
//            e.printStackTrace();
//        }

        OutputStream out = null;
        OutputStreamWriter outw = null;
        BufferedWriter bw = null;
        try{
            out = new FileOutputStream(file);
            outw = new OutputStreamWriter(out);
            bw = new BufferedWriter(outw);

            //包名
            bw.write("package " + Constants.PACKAGE_PO + ";");
            bw.newLine();
            bw.newLine();

            //导包
            bw.write("import java.io.Serializable;");
            bw.newLine();
            if(tableInfo.getHavaBigDecimal()){
                bw.write("import java.math.BigDecimal;");
                bw.newLine();
            }
            if(tableInfo.getHavaDate() || tableInfo.getHavaDateTime()){
                bw.write("import java.util.Date;");
                bw.newLine();
                bw.write(Constants.BEAN_DATE_FORMAT_CLASS + ";");
                bw.newLine();
                bw.write(Constants.BEAN_DATE_UNFORMAT_CLASS + ";");
                bw.newLine();

                bw.write("import " + Constants.PACKAGE_UTILS + ".DateUtils;");
                bw.newLine();
                bw.write("import " + Constants.PACKAGE_ENUMS + ".DateTimePatternEnum;");
                bw.newLine();
            }
            Boolean haveIgnoreBean = false;
            for(FieldInfo fieldInfo : tableInfo.getFieldList()){
                if(ArrayUtils.contains(Constants.IGNORE_BEAN_TOJSON_FIELDS.split( ","), fieldInfo.getPropertyName())){
                    haveIgnoreBean = true;
                    break;
                }
            }
            if(haveIgnoreBean){
                bw.write(Constants.IGNORE_BEAN_TOJSON_CLASS + ";");
                bw.newLine();
            }
            bw.newLine();
            bw.newLine();

            //构建类注释
            BuildComment.createClassComment(bw, tableInfo.getComment());
            bw.write("public class "+tableInfo.getBeanName()+" implements Serializable{");
            bw.newLine();
            bw.newLine();

            for(FieldInfo fieldInfo : tableInfo.getFieldList()){
                //构建字段注释
                BuildComment.createFieldComment(bw, fieldInfo.getComment());
                //构建注解
                if(ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES, fieldInfo.getSqlType())){
                    bw.write("\t" + String.format(Constants.BEAN_DATE_FORMAT_EXPRESSION, DateUtils.YYYY_MM_DD_HH_MM_SS));
                    bw.newLine();
                    bw.write("\t" + String.format(Constants.BEAN_DATE_UNFORMAT_EXPRESSION, DateUtils.YYYY_MM_DD_HH_MM_SS));
                    bw.newLine();
                }
                if(ArrayUtils.contains(Constants.SQL_DATE_TYPES, fieldInfo.getSqlType())){
                    bw.write("\t" + String.format(Constants.BEAN_DATE_FORMAT_EXPRESSION, DateUtils.YYYY_MM_DD));
                    bw.newLine();
                    bw.write("\t" + String.format(Constants.BEAN_DATE_UNFORMAT_EXPRESSION, DateUtils.YYYY_MM_DD));
                    bw.newLine();
                }
                if(ArrayUtils.contains(Constants.IGNORE_BEAN_TOJSON_FIELDS.split( ","), fieldInfo.getPropertyName())){
                    bw.write("\t" + Constants.IGNORE_BEAN_TOJSON_EXPRESSIONS);
                    bw.newLine();
                }

                bw.write("\tprivate " + fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName() + ";");
                bw.newLine();
                bw.newLine();
            }

            //构建getter和setter方法
            for(FieldInfo fieldInfo : tableInfo.getFieldList()){
                String tempField = StringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName());
                bw.write("\tpublic void set" + tempField + "(" + fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName() + ") {");
                bw.newLine();
                bw.write("\t\tthis." + fieldInfo.getPropertyName() + " = " + fieldInfo.getPropertyName() + ";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();
                bw.write("\tpublic " + fieldInfo.getJavaType() + " get" + tempField + "() {");
                bw.newLine();
                bw.write("\t\treturn " + fieldInfo.getPropertyName() + ";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();
            }

            //重写toString方法
            StringBuffer toString = new StringBuffer();
            Integer index = 0;
            for(FieldInfo field : tableInfo.getFieldList()){
                index++;

                String propertyName = field.getPropertyName();
                if(ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES, field.getSqlType())){
                    propertyName = "DateUtils.format(" + propertyName + ", DateTimePatternEnum.YYYY_MM_DD_HH_MM_SS.getPattern())";
                } else if (ArrayUtils.contains(Constants.SQL_DATE_TYPES, field.getSqlType())) {
                    propertyName = "DateUtils.format(" + propertyName + ", DateTimePatternEnum.YYYY_MM_DD.getPattern())";
                }
                toString.append(field.getComment() + ":\" + " + propertyName);
                if(index < tableInfo.getFieldList().size()){
                    toString.append(" + \", ");
                }
            }
            toString.insert(0, "\"");

            bw.write("\t@Override");
            bw.newLine();
            bw.write("\tpublic String toString() {");
            bw.newLine();
            bw.write("\t\treturn "+toString.toString()+";");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();

            bw.write("}");
            bw.flush();

        }catch (Exception e){
            logger.error("创建po失败", e);
        }finally {
            try{
                if(bw != null){
                    bw.close();
                }
                if(outw != null){
                    outw.close();
                }
                if(out != null){
                    out.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
